import os
import asyncio
import time
from datetime import datetime, timedelta
from typing import Dict, Set, Optional
from pathlib import Path
from app.config.logging_config import get_logger

# 获取音频模块专用的日志记录器
logger = get_logger(__name__, "audio")


class AudioFileManager:
    """音频文件管理器，负责跟踪和清理已播放的音频文件"""
    
    def __init__(self, audio_dir: str = "audio_files"):
        self.audio_dir = Path(audio_dir)
        self.played_files: Set[str] = set()  # 已播放的文件集合
        self.file_info: Dict[str, dict] = {}  # 文件信息字典
        self.cleanup_interval = 300  # 清理间隔（秒），默认5分钟
        self.max_file_age = 3600  # 文件最大保留时间（秒），默认1小时
        self._cleanup_task: Optional[asyncio.Task] = None
        
        # 确保音频目录存在
        self.audio_dir.mkdir(exist_ok=True)
        logger.info(f"🎵 音频文件管理器初始化，目录: {self.audio_dir}")
    
    def register_audio_file(self, filename: str, file_path: str = None) -> None:
        """注册新生成的音频文件
        
        Args:
            filename: 音频文件名
            file_path: 完整文件路径（可选）
        """
        if not file_path:
            file_path = str(self.audio_dir / filename)
        
        self.file_info[filename] = {
            'path': file_path,
            'created_at': datetime.now(),
            'played': False,
            'play_count': 0,
            'last_played': None
        }
        
        logger.info(f"📝 注册音频文件: {filename}")
    
    def mark_as_played(self, filename: str) -> None:
        """标记音频文件为已播放
        
        Args:
            filename: 音频文件名
        """
        if filename in self.file_info:
            self.file_info[filename]['played'] = True
            self.file_info[filename]['play_count'] += 1
            self.file_info[filename]['last_played'] = datetime.now()
            self.played_files.add(filename)
            logger.info(f"✅ 标记音频文件已播放: {filename}")
        else:
            logger.warning(f"⚠️ 尝试标记未注册的音频文件: {filename}")
    
    def mark_as_played_by_url(self, audio_url: str) -> None:
        """根据音频URL标记文件为已播放
        
        Args:
            audio_url: 音频文件URL，格式如 '/audio/filename.mp3'
        """
        # 从URL中提取文件名
        if audio_url.startswith('/audio/'):
            filename = audio_url.replace('/audio/', '')
            self.mark_as_played(filename)
        else:
            logger.warning(f"⚠️ 无效的音频URL格式: {audio_url}")
    
    def delete_played_files(self) -> int:
        """删除所有已播放的音频文件
        
        Returns:
            删除的文件数量
        """
        deleted_count = 0
        files_to_remove = []
        
        for filename in self.played_files.copy():
            if filename in self.file_info:
                file_path = self.file_info[filename]['path']
                try:
                    if os.path.exists(file_path):
                        os.remove(file_path)
                        logger.info(f"🗑️ 删除已播放音频文件: {filename}")
                        deleted_count += 1
                    
                    # 从记录中移除
                    files_to_remove.append(filename)
                    
                except Exception as e:
                    logger.error(f"❌ 删除音频文件失败 {filename}: {str(e)}")
        
        # 清理记录
        for filename in files_to_remove:
            self.played_files.discard(filename)
            self.file_info.pop(filename, None)
        
        if deleted_count > 0:
            logger.info(f"🧹 清理完成，删除了 {deleted_count} 个已播放的音频文件")
        
        return deleted_count
    
    def delete_old_files(self) -> int:
        """删除超过最大保留时间的音频文件
        
        Returns:
            删除的文件数量
        """
        deleted_count = 0
        current_time = datetime.now()
        files_to_remove = []
        
        for filename, info in self.file_info.items():
            file_age = (current_time - info['created_at']).total_seconds()
            
            if file_age > self.max_file_age:
                file_path = info['path']
                try:
                    if os.path.exists(file_path):
                        os.remove(file_path)
                        logger.info(f"🗑️ 删除过期音频文件: {filename} (年龄: {file_age:.0f}秒)")
                        deleted_count += 1
                    
                    files_to_remove.append(filename)
                    
                except Exception as e:
                    logger.error(f"❌ 删除过期音频文件失败 {filename}: {str(e)}")
        
        # 清理记录
        for filename in files_to_remove:
            self.played_files.discard(filename)
            self.file_info.pop(filename, None)
        
        if deleted_count > 0:
            logger.info(f"🧹 清理完成，删除了 {deleted_count} 个过期的音频文件")
        
        return deleted_count
    
    def cleanup_all(self) -> dict:
        """执行完整的清理操作
        
        Returns:
            清理结果统计
        """
        logger.info("🧹 开始执行音频文件清理...")
        
        played_deleted = self.delete_played_files()
        old_deleted = self.delete_old_files()
        
        result = {
            'played_files_deleted': played_deleted,
            'old_files_deleted': old_deleted,
            'total_deleted': played_deleted + old_deleted,
            'remaining_files': len(self.file_info)
        }
        
        logger.info(f"🧹 清理完成: {result}")
        return result
    
    def get_file_stats(self) -> dict:
        """获取文件统计信息
        
        Returns:
            文件统计信息
        """
        total_files = len(self.file_info)
        played_files = len(self.played_files)
        unplayed_files = total_files - played_files
        
        # 计算文件大小
        total_size = 0
        for info in self.file_info.values():
            if os.path.exists(info['path']):
                total_size += os.path.getsize(info['path'])
        
        return {
            'total_files': total_files,
            'played_files': played_files,
            'unplayed_files': unplayed_files,
            'total_size_bytes': total_size,
            'total_size_mb': round(total_size / (1024 * 1024), 2)
        }
    
    async def start_auto_cleanup(self) -> None:
        """启动自动清理任务"""
        if self._cleanup_task and not self._cleanup_task.done():
            logger.warning("⚠️ 自动清理任务已在运行")
            return
        
        logger.info(f"🚀 启动自动清理任务，间隔: {self.cleanup_interval}秒")
        self._cleanup_task = asyncio.create_task(self._auto_cleanup_loop())
    
    async def stop_auto_cleanup(self) -> None:
        """停止自动清理任务"""
        if self._cleanup_task and not self._cleanup_task.done():
            self._cleanup_task.cancel()
            try:
                await self._cleanup_task
            except asyncio.CancelledError:
                pass
            logger.info("🛑 自动清理任务已停止")
    
    async def _auto_cleanup_loop(self) -> None:
        """自动清理循环"""
        while True:
            try:
                await asyncio.sleep(self.cleanup_interval)
                self.cleanup_all()
            except asyncio.CancelledError:
                logger.info("🛑 自动清理循环被取消")
                break
            except Exception as e:
                logger.error(f"❌ 自动清理过程中发生错误: {str(e)}")
                # 继续运行，不因单次错误而停止


# 创建全局音频文件管理器实例
audio_manager = AudioFileManager()